package org.xtremeobjects.domain.model;

import java.lang.annotation.Annotation;
import java.util.List;

import org.xtremeobjects.anotations.ddd.Repository;


public interface Clazz {

	/**
	 * 
	 * @return an array of properties names
	 */
	public String[] getPropertiesNames();

	/**
	 * @return a list of class properties
	 */
	public List<Property> getProperties();

	public List<Association> getAssociations();

	public List<Operation> getOperations();
	
	/**
	 * Returns just public operations not including
	 * getters, setters, adds and removes to collections.
	 * @return
	 */
	public List<Operation> getPublicOperations();
	
	/**
	 * 
	 * @return Clazz name
	 */
	public String getName();

	/**
	 * 
	 * @return the real Class of this clazz
	 */
	public Class<?> getImplementationClass();

	public String[] getAssociationsNames();

	//Annotation and instance dependant things
	
	/**
	 * Returns the label of an object from it's annotation.
	 * If the @Label annotation contains an EL expression it is evaluated with "self" as the
	 * object that was passed as a parameter.
	 * If there is no annotation it returns obj.toString()
	 */
	public String getLabel(Object obj);

	/**
	 * 
	 * @param obj - object to get the description from
	 * @return the description of the object, that cames from @Description
	 */
	public String getDescription(Object obj); 

	/**
	 * Returns a string with the ID for an object in case it has it,
	 * otherwise it returns null.
	 * @param obj
	 * @return an String containing the id of the object if it exists or null
	 */
	public String getId(Object obj);

	/**
	 * Is this clazz a repository?
	 * @return true if this clazz is a repository
	 */
	@Deprecated
	public boolean isRepository();
	
	public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
	
	public <A extends Annotation> A getAnnotation(Class<A> annotationClass);
	
	@Deprecated
	public Repository getRepositoryAnnotation();

	/**
	 * 
	 * @return clazz superclazz or null if clazz has no superclazzes
	 */
	public Clazz getSuperclazz();

	/**
	 * 
	 * @return a name without the packages
	 */
	public String getSimpleName();
}